package com.useeinfo.oa.modules.base.biz;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.useeinfo.framework.extend.biz.CrudBiz;
import com.useeinfo.framework.sugar.data.QueryParam;
import com.useeinfo.framework.sugar.func.lang.StringUtils;
import com.useeinfo.framework.sugar.tools.Configuration;
import com.useeinfo.framework.sugar.tools.DateTimeUtils;
import com.useeinfo.framework.sugar.tools.StringConverters;
import com.useeinfo.oa.common.enums.ResultEnums;
import com.useeinfo.oa.common.utils.ResultUtil.ResultDto;
import com.useeinfo.oa.common.utils.ResultUtil.ResultUtil;
import com.useeinfo.oa.modules.base.dao.MessageDao;
import com.useeinfo.oa.modules.base.entity.ApplicationModule;
import com.useeinfo.oa.modules.base.entity.Enterprise;
import com.useeinfo.oa.modules.base.entity.Message;
import com.useeinfo.oa.modules.base.entity.PlanMessageSend;
import com.useeinfo.oa.modules.base.enums.MessageTypeEnum;
import com.useeinfo.oa.modules.base.vo.MessageVO;
import com.useeinfo.oa.modules.inspection.biz.InspectionOrderBiz;
import com.useeinfo.oa.modules.inspection.entity.InspectionOrder;
import com.useeinfo.oa.modules.maintaining.biz.MaintainOrderBiz;
import com.useeinfo.oa.modules.maintaining.entity.MaintainOrder;
import com.useeinfo.oa.modules.repair.biz.RepairOrderBiz;
import com.useeinfo.oa.modules.repair.entity.RepairOrder;
import com.useeinfo.oa.modules.security.biz.SystemAuthorityBiz;
import com.useeinfo.oa.modules.security.biz.SystemUserBiz;
import com.useeinfo.oa.modules.security.biz.UserDeviceBiz;
import com.useeinfo.oa.modules.security.entity.SystemUser;
import com.useeinfo.oa.modules.security.entity.UserDevice;
import com.useeinfo.oa.modules.security.util.SessionKeyUtils;
import com.useeinfo.oa.modules.task.biz.TaskOrderBiz;
import com.useeinfo.oa.modules.task.entity.TaskOrder;
import com.useeinfo.oa.modules.threadUtil.ThreadUtils;
import com.useeinfo.oa.modules.threadUtil.message.PushDeviceMessage;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Auther: xudong.sun
 * @Date: 2019/1/15 16:06
 * @Description:
 */
@Service
public class MessageBiz extends CrudBiz<MessageDao, Message> {

    @Autowired
    private HttpServletRequest httpServletRequest;

    @Autowired
    private PlanMessageSendBiz planMessageSendBiz;

    @Autowired
    private MaintainOrderBiz maintainOrderBiz;

    @Autowired
    private UserDeviceBiz userDeviceBiz;

    @Autowired
    private SystemUserBiz systemUserBiz;

    @Autowired
    private EnterpriseBiz enterpriseBiz;

    @Autowired
    private RepairOrderBiz repairOrderBiz;
    @Autowired
    private TaskOrderBiz taskOrderBiz;

    @Autowired
    private InspectionOrderBiz inspectionOrderBiz;

    @Autowired
    private ApplicationModuleBiz applicationModuleBiz;
    @Autowired
    private SystemAuthorityBiz systemAuthorityBiz;


    public ResultDto getType() {
        Enterprise sessionEnterprise = SessionKeyUtils.getSessionEnterprise(httpServletRequest);
        SystemUser systemUser = SessionKeyUtils.getSessionUser(httpServletRequest);
        if (systemUser == null || sessionEnterprise == null) {
            ResultUtil.error(ResultEnums.NO_LOGIN_MESSAGE);
        }

        String applicationHql = "select obj from ApplicationModule obj where obj.deleteStatus is false and obj.remark in ('MAINTAIN','INSPECTION','REPAIR','AUTO','TASK') and exists(select o from obj.enterpriseSet o where o.id=" + sessionEnterprise.getId() + ")";
        List<ApplicationModule> applicationModuleList = applicationModuleBiz.hqlExcute(applicationHql);
        JSONArray jsonArray = new JSONArray();
        for (ApplicationModule applicationModule : applicationModuleList) {
            JSONObject object = new JSONObject();
            object.put("remark", applicationModule.getRemark());
            QueryParam numParam = new QueryParam();
            numParam.getSqlMap().put("messageType",applicationModule.getRemark());
            numParam.getSqlMap().put("enterpriseId",StringConverters.null2String(sessionEnterprise.getId()));
            numParam.getSqlMap().put("sendToUserId", StringConverters.null2String(systemUser.getId()));
            numParam.getSqlMap().put("readStatus","false");
            List<Message> msg = findList(numParam);
            QueryParam queryParam = new QueryParam();
            queryParam.getSqlMap().put("messageType",applicationModule.getRemark());
            queryParam.getSqlMap().put("enterpriseId",StringConverters.null2String(sessionEnterprise.getId()));
            queryParam.getSqlMap().put("sendToUserId", StringConverters.null2String(systemUser.getId()));
            queryParam.setSqlOrder("order by createDate desc");
            List<Message> messages = findList(queryParam);
            if(CollectionUtils.isNotEmpty(messages)){
                Message message = messages.get(0);
                object.put("content",message.getContent());
                object.put("createDate", DateTimeUtils.format(message.getCreateDate(),"HH:mm"));
            }
            if("MAINTAIN".equals(applicationModule.getRemark())){
                object.put("title","工作通知：维保");
                object.put("num",msg.size());
                object.put("name", applicationModule.getApplicationName());
            } else if ("INSPECTION".equals(applicationModule.getRemark())) {
                object.put("title","工作通知：巡检");
                object.put("num",msg.size());
                object.put("name", applicationModule.getApplicationName());
            }else if("REPAIR".equals(applicationModule.getRemark())){
                object.put("title","工作通知：维修");
                object.put("num",msg.size());
                object.put("name", applicationModule.getApplicationName());
            }else if("AUTO".equals(applicationModule.getRemark())){
                object.put("title","工作通知：自动报修");
                object.put("num",msg.size());
                object.put("name", applicationModule.getApplicationName());
            }else if("TASK".equals(applicationModule.getRemark())){
                object.put("title","工作通知：任务工单");
                object.put("num",msg.size());
            }
            jsonArray.add(object);
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("rows", jsonArray);
        return ResultUtil.success(jsonObject);
    }


    public ResultDto messageList(String pageIndex, String pageSize, String searchParam, String type, Boolean readStatus, String deviceToken, String deviceType) {
        JSONObject result = new JSONObject();
        SystemUser systemUser = SessionKeyUtils.getSessionUser(httpServletRequest);
        Enterprise sessionEnterprise = SessionKeyUtils.getSessionEnterprise(httpServletRequest);
        if (systemUser == null || sessionEnterprise == null) {
            ResultUtil.error(ResultEnums.NO_LOGIN_MESSAGE);
        }

        QueryParam queryParam = new QueryParam(pageIndex, pageSize);
        if (StringUtils.isNotBlank(searchParam)) {
            queryParam.getSqlMap().put("searchParam", searchParam);
        }

        if (StringUtils.isNotBlank(type)) {
            queryParam.getSqlMap().put("messageType", type);
        }

        if (readStatus != null) {
            queryParam.getSqlMap().put("readStatus", StringConverters.null2String(readStatus));
        }
        if (deviceType != null) {
            queryParam.getSqlMap().put("deviceType", deviceType);
        }
//        if (deviceToken != null) {
//            queryParam.getSqlMap().put("deviceToken", deviceToken);
//        }

        queryParam.getSqlMap().put("enterpriseId", StringConverters.null2String(sessionEnterprise.getId()));
        queryParam.getSqlMap().put("sendToUserId", StringConverters.null2String(systemUser.getId()));
        List<Message> messages = dao.findList(queryParam);
        JSONArray jsonArray = new JSONArray();
        Long id = 0L;
        for (Message message : messages) {
            JSONObject jsonObject = message.toJSONObject();
            QueryParam queryParam1 = new QueryParam();
            String code = message.getCode();
            if(MessageTypeEnum.REPAIR.equals(message.getMessageTypeEnum())){
                queryParam1.getSqlMap().put("reportCode",code);
                List<RepairOrder> repairOrders =  repairOrderBiz.findList(queryParam1);
                if(CollectionUtils.isNotEmpty(repairOrders)){
                    id = repairOrders.get(0).getId();
                }
            }else if(MessageTypeEnum.MAINTAIN.equals(message.getMessageTypeEnum())){
                queryParam1.getSqlMap().put("maintainCode",code);
                List<MaintainOrder> maintainOrders = maintainOrderBiz.findList(queryParam1);
                if(CollectionUtils.isNotEmpty(maintainOrders)){
                    id = maintainOrders.get(0).getId();
                }
            }else if(MessageTypeEnum.INSPECTION.equals(message.getMessageTypeEnum())){
                queryParam1.getSqlMap().put("orderCode",code);
                List<InspectionOrder> inspectionOrders = inspectionOrderBiz.findList(queryParam1);
                if(CollectionUtils.isNotEmpty(inspectionOrders)){
                    id = inspectionOrders.get(0).getId();
                }
            }else if(MessageTypeEnum.AUTO.equals(message.getMessageTypeEnum())){
                queryParam1.getSqlMap().put("reportCode",code);
                List<RepairOrder> repairOrders = repairOrderBiz.findList(queryParam1);
                if(CollectionUtils.isNotEmpty(repairOrders)){
                    id = repairOrders.get(0).getId();
                }
            }
            else if(MessageTypeEnum.TASK.equals(message.getMessageTypeEnum())){
                queryParam1.getSqlMap().put("serial",code);
                List<TaskOrder> taskOrders = taskOrderBiz.findList(queryParam1);
                if(CollectionUtils.isNotEmpty(taskOrders)){
                    id = taskOrders.get(0).getId();
                }
            }
            jsonObject.put("id",id);
            jsonArray.add(jsonObject);
        }
        result.put("rows", jsonArray);
        return ResultUtil.success(result);
    }

    @Transactional
    public ResultDto sendPlanMessage(List<PlanMessageSend> planMessageSends) {
        Date now = new Date();
        for (PlanMessageSend planMessageSend : planMessageSends) {
            String content = "";
                List<MessageVO> messageVOS = new ArrayList<>();
                List<SystemUser> users = new ArrayList<>();
                QueryParam deveiceParam = new QueryParam();
                deveiceParam.getSqlMap().put("userId", StringConverters.null2String(planMessageSend.getSendToUser().getId()));
                List<UserDevice> userDevices = userDeviceBiz.findList(deveiceParam);
                users.add(systemUserBiz.findModel(StringConverters.null2Long(planMessageSend.getSendToUser().getId())));
                for (UserDevice userDevice : userDevices) {
                    messageVOS.add(new MessageVO(userDevice.getDeviceType(), userDevice.getDeviceToken()));
                }
                if(MessageTypeEnum.MAINTAIN.getCode().equals(planMessageSend.getMessageTypeEnum().getCode())){
                    content = "维保单" + planMessageSend.getOrderCode() + "等待接单!";
                    if (CollectionUtils.isNotEmpty(messageVOS)) {
                        PushDeviceMessage pushDeviceMessage = new PushDeviceMessage(messageVOS,content, MessageTypeEnum.MAINTAIN, this,StringConverters.null2String(planMessageSend.getEnterprise().getId()),planMessageSend.getOrderCode());
                        messageVOS.forEach(messageVO -> {
                                pushDeviceMessage.SendMessage(messageVO.getDeviceType(), messageVO.getDeviceToken());
                        });
                    }
                }else if(MessageTypeEnum.INSPECTION.getCode().equals(planMessageSend.getMessageTypeEnum().getCode())){
                    content = "巡检单" + planMessageSend.getOrderCode() + "等待接单!";
                    if (CollectionUtils.isNotEmpty(messageVOS)) {
                        PushDeviceMessage pushDeviceMessage = new PushDeviceMessage(messageVOS, content, MessageTypeEnum.INSPECTION, this,StringConverters.null2String(planMessageSend.getEnterprise().getId()),planMessageSend.getOrderCode());
                        messageVOS.forEach(messageVO -> {
                            pushDeviceMessage.SendMessage(messageVO.getDeviceType(), messageVO.getDeviceToken());
                        });
                    }
                }
        }
        return ResultUtil.success();
    }

    @Transactional
    public String saveMessage(String message, String clientid, MessageTypeEnum messageTypeEnum,String enterpriseId,String code,String type,String token) {
        Enterprise enterprise = null;
        if(StringUtils.isNotBlank(enterpriseId)){
            enterprise = enterpriseBiz.findModel(StringConverters.null2Long(enterpriseId));
        }
        Message mess = new Message(message, message, userDeviceBiz.getUserMessage(clientid), messageTypeEnum, enterprise,code,type,token);
        this.addOrUpdate(mess);
        return StringConverters.null2String(mess.getId());
    }

    public ResultDto messageDetail(String id){
        Message message = dao.findModel(StringConverters.null2Long(id));
        message.setReadStatus(true);
        dao.update(message);
        return ResultUtil.success();
    }
}
